﻿using System;
using System.ComponentModel;
using Caliburn.Micro;
using NHibernate;
using TimeKeeper.Entities;
using TimeKeeper.Events;
using TimeKeeper.Infrastructure;
using System.Linq;

namespace TimeKeeper.ViewModels
{
    public class TimeEditViewModel : Screen
    {
        public override string DisplayName { get { return "Time Edit"; } set { } }

        private ProjectTime _timeOnProject;
        public ProjectTime TimeOnProject
        {
            get { return _timeOnProject; }
            set { _timeOnProject = ViewModelHelper.SetValueWithRegistration(value, _timeOnProject, WhenTimeOnProjectChanged); }
        }

        private void WhenTimeOnProjectChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            NotifyOfPropertyChange(() => CanOk);
        }

        private readonly ISession _session;
        private readonly IEventAggregator _eventAggregator;
        private readonly IEntityFactory _entityFactory;
        private ChangeType _changeType;

        public TimeEditViewModel(ISession session, IEventAggregator eventAggregator, IEntityFactory entityFactory)
        {
            _session = session;
            _eventAggregator = eventAggregator;
            _entityFactory = entityFactory;
            TimeOnProject = _entityFactory.Create<ProjectTime>();
            TimeOnProject.Date = DateTime.Now;
            TimeOnProject.Time = 0f;
            _changeType = ChangeType.Added;
        }

        public TimeEditViewModel WithProject(int projectId)
        {
            _session.QueryInTransaction<Project>(q => TimeOnProject.Project = q.First(x => x.Id == projectId));
            return this;
        }

        public TimeEditViewModel WithTime(int timeId)
        {
            _session.QueryInTransaction<ProjectTime>(q => TimeOnProject = q.First(x => x.Id == timeId));
            _changeType = ChangeType.Modifed;
            return this;
        }

        public bool CanOk { get { return ViewModelHelper.IsValid(TimeOnProject); } }

        public void Ok()
        {
            _session.DoInTransaction(q => q.Save(TimeOnProject));
            _eventAggregator.Publish(new ProjectTimeChanged(TimeOnProject.Id, TimeOnProject.Project.Id, _changeType));
            TryClose(true);
        }

        public void Cancel()
        {
            TryClose(false);
        }
    }
}
